home *** CD-ROM | disk | FTP | other *** search
- /* GETF.C - locate the source file containing a specified function and
- * present it in your favorite editor.
- * Copyright (c) 1988 Marvin Hymowech
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define LINT_ARGS
-
- #define TRUE 1
- #define FALSE 0
- #define LINE_LEN 256
-
- /* function declarations */
- int patn_match(char *, char *);
- void edit(char *, char *);
- void ask_for_file(char **, char **, unsigned int);
-
- unsigned int num_ctl_patns; /* number of %s symbols in GETFEDIT var */
- char *file_token, *func_token;
- char arg1[64]; /* argument for editor command line */
- char *arg1_ctl; /* ctl string for building arg1 */
- char *pgm_name; /* name of editor to invoke */
-
- main(argc, argv)
- int argc;
- char **argv;
- {
-
- #define MAX_CHOICES 256
-
- char file_line[LINE_LEN], func_line[LINE_LEN];
- char func_name[64], edit_cmd[128];
- char *env_edit_cmd, *ctl_patn;
- unsigned int last_func, len, eof = FALSE;
- static char file_name[] = "FUNCS.TXT"; /* input file name */
- FILE *funcs_file;
- static char delim[] = "\n\t "; /* white space delimiters */
- unsigned int num_choices = 0;
- char *func_choices[MAX_CHOICES], *file_choices[MAX_CHOICES];
-
- if (argc != 2) {
- fprintf( stderr, "\ngetf: wrong number of arguments");
- exit(1);
- }
-
- /* the argument is the function name to find */
- strcpy( func_name, *++argv);
-
- if ( (env_edit_cmd = getenv( "GETFEDIT")) == NULL) {
- fprintf( stderr, "\ngetf: missing environment variable GETFEDIT");
- exit(1);
- }
-
- /* Check if GETFEDIT environment variable has a place for
- * function name as well as file name - note function name
- * is assumed to go in the first %s pattern if there are
- * two %s patterns.
- */
-
- if ( (ctl_patn = strstr(env_edit_cmd, "%s")) == NULL) {
- fprintf( stderr,
- "\ngetf: environment variable GETFEDIT has no %%s pattern");
- exit(1);
- }
-
- num_ctl_patns = strstr(++ctl_patn, "%s") == NULL ? 1 : 2;
- strcpy( edit_cmd, env_edit_cmd);
- if( (pgm_name = strtok( edit_cmd, " ")) == NULL) {
- fprintf( stderr,
- "\ngetf: environment variable GETFEDIT has incorrect format.");
- exit(1);
- }
-
- /* point to argument following program name */
- arg1_ctl = edit_cmd + strlen(pgm_name) + 1;
- if( (funcs_file = fopen(file_name, "r")) == NULL) {
- fprintf(stderr, "\ngetf: can't open %s\n", *argv);
- exit(1);
- }
-
- while ( !eof) { /* loop thru file names, which end with colon */
- if (fgets(file_line, LINE_LEN, funcs_file) == NULL)
- break;
- /* bypass any line consisting of white space */
- if ( (file_token = strtok(file_line, delim )) == NULL)
- continue;
- if (file_token[len = strlen(file_token) - 1] != ':') {
- fprintf(stderr, "getf: incorrect file format on %s", file_name);
- exit(1);
- }
- file_token [len] = 0; /* kill trailing colon */
- last_func = FALSE; /* set up to detect last func this file */
-
- while ( !eof && !last_func) { /* loop thru func names this file */
- /* last such ends with semicolon */
- if (fgets(func_line, LINE_LEN, funcs_file) == NULL) {
- eof = TRUE;
- break;
- }
- /* bypass any line consisting of white space */
- if ( (func_token = strtok(func_line, delim )) == NULL)
- continue;
- if (func_token [len = strlen(func_token) - 1] == ';') {
- last_func = TRUE; /* break loop after this one */
- func_token [len] = 0; /* kill trailing semi-colon */
- }
- if (patn_match(func_name, func_token)) {
- func_choices[num_choices] = strdup(func_token);
- file_choices[num_choices++] = strdup(file_token);
- }
- } /* while */
- } /* while */
-
- switch (num_choices) {
- case 0:
- fprintf(stderr, "getf: no match for %s in %s", func_name, file_name);
- exit(1);
- case 1:
- edit(func_choices[0], file_choices[0]);
- default:
- ask_for_file(func_choices, file_choices, num_choices);
- } /* switch */
- } /* end main() */
-
- /* Return TRUE if string "s" matches pattern 'patn',
- * or FALSE if it does not. Allowable wildcards in
- * patn are: ? for one character, % for any string
- * of characters up to the next underscore or end
- * of string, and * for any string of characters up
- * to end of string.
- */
-
- int patn_match(patn, s)
- char *patn; /* pattern */
- char *s; /* string */
- {
-
- for ( ; *patn; patn++) {
- if (!*s) /* if out of s chars, no match unless patn ends with * or & */
- return ((*patn == '*' || *patn == '%') && !*(patn + 1));
- switch(*patn) {
- case '%':
- while (*s != '_' && *s)
- s++;
- break;
- case '*':
- while (*s++)
- ;
- break;
- case '?':
- s++;
- break;
- default:
- if (*s != *patn)
- return FALSE;
- s++;
- } /* switch */
- } /* for */
- return *s == 0;
- } /* patn_match() */
-
- void ask_for_file(func_choices, file_choices, num_choices)
- char *func_choices[], *file_choices[];
- unsigned int num_choices;
- {
-
- int i;
- char line[LINE_LEN];
-
- while (TRUE) {
- printf( "Which one? (CR to exit)\n");
- for (i = 1; i <= num_choices; i++)
- printf( "\t%3d: %20.20s in % - 30.30s\n", i, func_choices [i - 1],
- file_choices [i - 1]);
- printf(" \nEnter number: ");
- fgets (line, LINE_LEN, stdin);
- if (line[0] == '\n')
- break;
- if ( (i = atoi(line)) < 1 || i > num_choices)
- printf( "Invalid choice:\007\n");
- else
- edit (func_choices [i - 1], file_choices [i - 1]);
- } /* while */
- } /* end ask_for-file() */
-
- void edit(func, file)
- char *func, *file;
- {
-
- /* execlp will overlay this program with the editor */
- if (num_ctl_patns == 1)
- sprintf (arg1, arg1_ctl, file);
- else
- sprintf (arg1, arg1_ctl, func, file);
- execlp (pgm_name, pgm_name, arg1, NULL);
-
- /* If we're still here, print error message */
- fprintf(stderr, "\ngetf: exec failed");
- exit(1);
- } /* end edit() */
-
-